BETANBINOM

Overview

The BETANBINOM function computes values for the beta-negative binomial distribution, a discrete probability distribution that models the number of failures before achieving a specified number of successes in a sequence of independent Bernoulli trials, where the probability of success itself varies according to a beta distribution. This makes it a compound probability distribution, combining the negative binomial distribution with a beta-distributed success probability.

The distribution is particularly useful when modeling overdispersed count data where the variance exceeds what the standard negative binomial distribution would predict. It finds applications in Bayesian statistics, reliability analysis, and modeling heterogeneous populations. The beta-negative binomial is also known as the inverse Markov-Pólya distribution or the generalized Waring distribution.

The probability mass function (PMF) is defined as:

f(k) = \binom{n+k-1}{k} \frac{B(a+n, b+k)}{B(a, b)}

where k \geq 0 is the number of failures, n \geq 0 is the number of successes, a > 0 and b > 0 are the shape parameters of the beta distribution, and B(a, b) is the beta function.

This implementation uses SciPy’s betanbinom from the scipy.stats module, which provides methods for computing the probability mass function (PMF), cumulative distribution function (CDF), survival function (SF), inverse CDF (ICDF/PPF), inverse survival function (ISF), and summary statistics including mean, variance, standard deviation, and median. The optional loc parameter shifts the distribution along the x-axis.

For more background on the mathematical properties of this distribution, see the Wikipedia article on the beta-negative binomial distribution.

This example function is provided as-is without any representation of accuracy.

Excel Usage

=BETANBINOM(k, n, a, b, betanbinom_mode, loc)
  • k (list[list], required): Value at which to evaluate (or probability for ICDF/ISF modes).
  • n (int, required): Number of successes (n >= 0).
  • a (float, required): Alpha parameter of the beta distribution (a > 0).
  • b (float, required): Beta parameter of the beta distribution (b > 0).
  • betanbinom_mode (str, optional, default: “pmf”): Output type to compute.
  • loc (float, optional, default: 0): Location parameter to shift the distribution.

Returns (float): Distribution result (float), or error message string.

Examples

Example 1: PMF at k=2

Inputs:

k n a b betanbinom_mode
2 5 9.3 1 pmf

Excel formula:

=BETANBINOM(2, 5, 9.3, 1, "pmf")

Expected output:

Result
0.0782

Example 2: CDF at k=2

Inputs:

k n a b betanbinom_mode
2 5 9.3 1 cdf

Excel formula:

=BETANBINOM(2, 5, 9.3, 1, "cdf")

Expected output:

Result
0.9411

Example 3: Survival function at k=2

Inputs:

k n a b betanbinom_mode loc
2 5 9.3 1 sf 0

Excel formula:

=BETANBINOM(2, 5, 9.3, 1, "sf", 0)

Expected output:

Result
0.0589

Example 4: Inverse CDF for probability 0.5

Inputs:

k n a b betanbinom_mode
0.5 5 9.3 1 icdf

Excel formula:

=BETANBINOM(0.5, 5, 9.3, 1, "icdf")

Expected output:

Result
0

Example 5: PMF for 2D array

Inputs:

k n a b betanbinom_mode
1 2 5 9.3 1 pmf
3 4

Excel formula:

=BETANBINOM({1,2;3,4}, 5, 9.3, 1, "pmf")

Expected output:

Result
0.2125 0.0782
0.0317 0.0138

Example 6: Mean of distribution

Inputs:

k n a b betanbinom_mode
0 5 9.3 1 mean

Excel formula:

=BETANBINOM(0, 5, 9.3, 1, "mean")

Expected output:

0.6024

Python Code

from scipy.stats import betanbinom as scipy_betanbinom

def betanbinom(k, n, a, b, betanbinom_mode='pmf', loc=0):
    """
    Compute Beta-negative-binomial distribution values: PMF, CDF, SF, ICDF, ISF, mean, variance, std, or median.

    See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.betanbinom.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        k (list[list]): Value at which to evaluate (or probability for ICDF/ISF modes).
        n (int): Number of successes (n >= 0).
        a (float): Alpha parameter of the beta distribution (a > 0).
        b (float): Beta parameter of the beta distribution (b > 0).
        betanbinom_mode (str, optional): Output type to compute. Valid options: PMF, CDF, SF, ICDF, ISF, Mean, Var, Std, Median. Default is 'pmf'.
        loc (float, optional): Location parameter to shift the distribution. Default is 0.

    Returns:
        float: Distribution result (float), or error message string.
    """
    # Validate n, a, b
    try:
        n_val = int(n)
        a_val = float(a)
        b_val = float(b)
        if not (n_val >= 0 and a_val > 0 and b_val > 0):
            return "Invalid input: n must be >= 0, a and b must be > 0."
    except Exception:
        return "Invalid input: n must be integer, a and b must be numbers."
    # Validate loc
    try:
        loc_val = float(loc)
    except Exception:
        return "Invalid input: loc must be a number."
    # Validate betanbinom_mode
    valid_modes = {"pmf", "cdf", "sf", "icdf", "isf", "mean", "var", "std", "median"}
    if not isinstance(betanbinom_mode, str) or betanbinom_mode not in valid_modes:
        return f"Invalid input: betanbinom_mode must be one of {sorted(valid_modes)}."

    # Helper to normalize input to 2D list
    def to2d(x):
        return [[x]] if not isinstance(x, list) else x

    # Handle statistics (k is ignored)
    if betanbinom_mode in ["mean", "var", "std", "median"]:
        if betanbinom_mode == "mean":
            return float(scipy_betanbinom.mean(n_val, a_val, b_val, loc=loc_val))
        if betanbinom_mode == "var":
            return float(scipy_betanbinom.var(n_val, a_val, b_val, loc=loc_val))
        if betanbinom_mode == "std":
            return float(scipy_betanbinom.std(n_val, a_val, b_val, loc=loc_val))
        if betanbinom_mode == "median":
            return float(scipy_betanbinom.median(n_val, a_val, b_val, loc=loc_val))

    # PMF, CDF, SF, ICDF, ISF
    k_2d = to2d(k)
    result = []
    for row in k_2d:
        if not isinstance(row, list):
             return "Invalid input: k must be a scalar or 2D list."
        result_row = []
        for val in row:
            try:
                kval = float(val)
            except Exception:
                return "Invalid input: k must be a number."

            if betanbinom_mode == "pmf":
                res = float(scipy_betanbinom.pmf(kval, n_val, a_val, b_val, loc=loc_val))
            elif betanbinom_mode == "cdf":
                res = float(scipy_betanbinom.cdf(kval, n_val, a_val, b_val, loc=loc_val))
            elif betanbinom_mode == "sf":
                res = float(scipy_betanbinom.sf(kval, n_val, a_val, b_val, loc=loc_val))
            elif betanbinom_mode == "icdf":
                res = float(scipy_betanbinom.ppf(kval, n_val, a_val, b_val, loc=loc_val))
            elif betanbinom_mode == "isf":
                res = float(scipy_betanbinom.isf(kval, n_val, a_val, b_val, loc=loc_val))
            result_row.append(res)
        result.append(result_row)

    # Return scalar if input was scalar
    if not isinstance(k, list) and len(result) == 1 and len(result[0]) == 1:
        return result[0][0]

    return result

Online Calculator